package com.adk.backend.controller;

import com.adk.backend.annotation.RequiresPermission;
import com.adk.backend.common.Result;
import com.adk.backend.entity.LxCDelivery;
import com.adk.backend.service.CDeliveryService;
import com.adk.backend.util.FileUploadUtil;
import com.adk.backend.util.JwtUtil;
import com.adk.backend.util.LogUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 派送单管理控制器
 */
@Slf4j
@RestController
@RequestMapping("/api/delivery")
public class CDeliveryController {
    
    @Autowired
    private CDeliveryService deliveryService;
    
    @Autowired
    private FileUploadUtil fileUploadUtil;
    
    @Autowired
    private LogUtil logUtil;
    
    @Autowired
    private JwtUtil jwtUtil;
    
    /**
     * 查询派送单列表
     */
    @RequiresPermission("list")
    @GetMapping("/list")
    public Result<List<Map<String, Object>>> getDeliveryList(
            @RequestParam(required = false) Long customerId,
            @RequestParam(required = false) String bookingDate,
            @RequestParam(required = false) Integer isBill,
            @RequestHeader(value = "Authorization", required = false) String token) {
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("customerId", customerId);
            params.put("bookingDate", bookingDate);
            params.put("isBill", isBill);
            
            List<Map<String, Object>> list = deliveryService.getDeliveryList(params);
            return Result.success(list);
        } catch (Exception e) {
            log.error("查询派送单列表失败", e);
            return Result.error("查询失败：" + e.getMessage());
        }
    }
    
    /**
     * 根据ID查询派送单详情
     */
    @RequiresPermission("view")
    @GetMapping("/detail")
    public Result<Map<String, Object>> getDeliveryDetail(@RequestParam Long id) {
        try {
            Map<String, Object> detail = deliveryService.getDeliveryDetailById(id);
            if (detail == null) {
                return Result.error("派送单不存在");
            }
            return Result.success(detail);
        } catch (Exception e) {
            log.error("查询派送单详情失败", e);
            return Result.error("查询失败：" + e.getMessage());
        }
    }
    
    /**
     * 保存派送单（新增或更新）
     */
    @RequiresPermission("edit")
    @PostMapping("/save")
    public Result<Boolean> saveDelivery(
            @RequestParam(required = false) Long id,
            @RequestParam String orderNo,
            @RequestParam Long customerId,
            @RequestParam Integer shipType,
            @RequestParam Integer totalCtns,
            @RequestParam java.math.BigDecimal totalGw,
            @RequestParam(required = false) String bookingNo,
            @RequestParam String bookingDate,
            @RequestParam(required = false) String remarks,
            @RequestHeader(value = "Authorization", required = false) String token,
            HttpServletRequest request) {
        try {
            Integer userId = getCurrentUserId(token);
            
            LxCDelivery delivery = new LxCDelivery();
            if (id != null && id > 0) {
                delivery.setId(id);
                delivery.setUpdateUid(userId);
                delivery.setUpdateTime((int) (System.currentTimeMillis() / 1000));
            } else {
                delivery.setAddUid(userId);
                delivery.setAddTime((int) (System.currentTimeMillis() / 1000));
            }
            
            delivery.setOrderNo(orderNo);
            delivery.setCustomerId(customerId);
            delivery.setShipType(shipType);
            delivery.setTotalCtns(totalCtns);
            delivery.setTotalGw(totalGw);
            delivery.setBookingNo(bookingNo);
            delivery.setBookingDate(bookingDate);
            delivery.setRemarks(remarks);
            delivery.setRecvd(0); // 默认未签收
            
            boolean success = deliveryService.saveDelivery(delivery);
            if (success) {
                String action = id != null && id > 0 ? "修改派送单" : "添加派送单";
                logUtil.logAction(getCurrentUserIdLong(token), null, "c_delivery", delivery.getId(), action, request);
                return Result.success("操作成功", true);
            } else {
                return Result.error("操作失败");
            }
        } catch (Exception e) {
            log.error("保存派送单失败", e);
            return Result.error("保存失败：" + e.getMessage());
        }
    }
    
    /**
     * 删除派送单
     */
    @RequiresPermission("del")
    @PostMapping("/del")
    public Result<Boolean> deleteDelivery(
            @RequestParam Long id,
            @RequestHeader(value = "Authorization", required = false) String token,
            HttpServletRequest request) {
        try {
            boolean success = deliveryService.deleteDelivery(id);
            if (success) {
                logUtil.logAction(getCurrentUserIdLong(token), null, "c_delivery", id, "删除派送单", request);
                return Result.success("删除成功", true);
            } else {
                return Result.error("删除失败");
            }
        } catch (Exception e) {
            log.error("删除派送单失败", e);
            return Result.error("删除失败：" + e.getMessage());
        }
    }
    
    /**
     * 更新备注
     */
    @RequiresPermission("edit")
    @PostMapping("/remarks")
    public Result<Boolean> updateRemarks(
            @RequestParam Long id,
            @RequestParam String remarks,
            @RequestHeader(value = "Authorization", required = false) String token,
            HttpServletRequest request) {
        try {
            Integer userId = getCurrentUserId(token);
            boolean success = deliveryService.updateRemarks(id, remarks, userId);
            if (success) {
                logUtil.logAction(getCurrentUserIdLong(token), null, "c_delivery", id, "更新备注", request);
                return Result.success("操作成功", true);
            } else {
                return Result.error("操作失败");
            }
        } catch (Exception e) {
            log.error("更新备注失败", e);
            return Result.error("更新失败：" + e.getMessage());
        }
    }
    
    /**
     * 更新预约日期
     */
    @RequiresPermission("edit")
    @PostMapping("/booking-date")
    public Result<Boolean> updateBookingDate(
            @RequestParam Long id,
            @RequestParam String bookingDate,
            @RequestHeader(value = "Authorization", required = false) String token,
            HttpServletRequest request) {
        try {
            Integer userId = getCurrentUserId(token);
            boolean success = deliveryService.updateBookingDate(id, bookingDate, userId);
            if (success) {
                logUtil.logAction(getCurrentUserIdLong(token), null, "c_delivery", id, "更新预约日期: " + bookingDate, request);
                return Result.success("操作成功", true);
            } else {
                return Result.error("操作失败");
            }
        } catch (Exception e) {
            log.error("更新预约日期失败", e);
            return Result.error("更新失败：" + e.getMessage());
        }
    }
    
    /**
     * 保存签收信息和POD
     */
    @RequiresPermission("edit")
    @PostMapping("/recv")
    public Result<Boolean> saveRecvInfo(
            @RequestParam Long id,
            @RequestParam Integer recvType,
            @RequestParam(required = false) String recvNo,
            @RequestParam String recvDate,
            @RequestParam(required = false) MultipartFile[] podFiles,
            @RequestHeader(value = "Authorization", required = false) String token,
            HttpServletRequest request) {
        try {
            Integer userId = getCurrentUserId(token);
            
            // 处理POD文件上传
            String pod = null;
            if (podFiles != null && podFiles.length > 0) {
                List<String> fileUrls = new java.util.ArrayList<>();
                for (MultipartFile file : podFiles) {
                    if (!file.isEmpty()) {
                        String fileUrl = fileUploadUtil.uploadFileToLocal(file, "uploads/c_delivery", userId, null);
                        fileUrls.add(fileUrl);
                    }
                }
                if (!fileUrls.isEmpty()) {
                    pod = String.join(",", fileUrls);
                }
            }
            
            boolean success = deliveryService.updateRecvInfo(id, recvType, recvNo, recvDate, pod, userId);
            if (success) {
                logUtil.logAction(getCurrentUserIdLong(token), null, "c_delivery", id, "上传POD签收单", request);
                return Result.success("操作成功", true);
            } else {
                return Result.error("操作失败");
            }
        } catch (Exception e) {
            log.error("保存签收信息失败", e);
            return Result.error("保存失败：" + e.getMessage());
        }
    }
    
    /**
     * 文件预览/下载接口（带权限控制）
     */
    @RequiresPermission("view")
    @GetMapping("/file")
    public ResponseEntity<Resource> previewOrDownloadFile(
            @RequestParam String filePath,
            @RequestParam(required = false, defaultValue = "false") Boolean download,
            @RequestHeader(value = "Authorization", required = false) String token) {
        try {
            // 验证文件路径是否合法（防止路径遍历攻击）
            String cleanPath = filePath.startsWith("./") ? filePath.substring(2) : filePath;
            if (cleanPath.contains("..") || !cleanPath.startsWith("uploads/c_delivery/")) {
                return ResponseEntity.badRequest().build();
            }
            
            File file = new File(cleanPath);
            if (!file.exists() || !file.isFile()) {
                return ResponseEntity.notFound().build();
            }
            
            Resource resource = new FileSystemResource(file);
            String fileName = file.getName();
            
            // 根据文件扩展名确定Content-Type
            String contentType = "application/octet-stream";
            String lowerFileName = fileName.toLowerCase();
            if (lowerFileName.endsWith(".jpg") || lowerFileName.endsWith(".jpeg")) {
                contentType = "image/jpeg";
            } else if (lowerFileName.endsWith(".png")) {
                contentType = "image/png";
            } else if (lowerFileName.endsWith(".pdf")) {
                contentType = "application/pdf";
            } else if (lowerFileName.endsWith(".xls") || lowerFileName.endsWith(".xlsx")) {
                contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
            } else if (lowerFileName.endsWith(".txt")) {
                contentType = "text/plain";
            } else if (lowerFileName.endsWith(".csv")) {
                contentType = "text/csv";
            }
            
            HttpHeaders headers = new HttpHeaders();
            if (download) {
                headers.setContentDispositionFormData("attachment", fileName);
            } else {
                headers.setContentDispositionFormData("inline", fileName);
            }
            headers.setContentType(MediaType.parseMediaType(contentType));
            
            return ResponseEntity.ok()
                    .headers(headers)
                    .body(resource);
        } catch (Exception e) {
            log.error("文件访问失败", e);
            return ResponseEntity.internalServerError().build();
        }
    }
    
    /**
     * 标记应收
     */
    @RequiresPermission("edit")
    @PostMapping("/mark-receivable")
    public Result<Boolean> markReceivable(
            @RequestParam Long id,
            @RequestHeader(value = "Authorization", required = false) String token,
            HttpServletRequest request) {
        try {
            boolean success = deliveryService.markReceivable(id);
            if (success) {
                logUtil.logAction(getCurrentUserIdLong(token), null, "c_delivery", id, "标记应收", request);
                return Result.success("操作成功", true);
            } else {
                return Result.error("操作失败");
            }
        } catch (Exception e) {
            log.error("标记应收失败", e);
            return Result.error("操作失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取当前用户ID（从token中获取）
     */
    private Integer getCurrentUserId(String token) {
        try {
            if (token != null && !token.isEmpty()) {
                if (token.startsWith("Bearer ")) {
                    token = token.substring(7);
                }
                Long userId = jwtUtil.getUserIdFromToken(token);
                return userId != null ? userId.intValue() : 1;
            }
        } catch (Exception e) {
            log.warn("获取用户ID失败", e);
        }
        return 1;
    }
    
    private Long getCurrentUserIdLong(String token) {
        Integer userId = getCurrentUserId(token);
        return userId != null ? userId.longValue() : null;
    }
    
    /**
     * 获取账单编辑信息
     */
    @RequiresPermission("view")
    @GetMapping("/billing-info")
    public Result<Map<String, Object>> getBillingInfo(
            @RequestParam Long deliveryId) {
        try {
            Map<String, Object> result = deliveryService.getBillingInfo(deliveryId);
            return Result.success(result);
        } catch (Exception e) {
            log.error("获取账单信息失败", e);
            return Result.error("获取账单信息失败：" + e.getMessage());
        }
    }
    
    /**
     * 保存账单（创建或更新）
     */
    @RequiresPermission("edit")
    @PostMapping("/save-billing")
    public Result<Boolean> saveBilling(
            @RequestParam Long deliveryId,
            @RequestBody Map<String, Object> billingData,
            @RequestHeader(value = "Authorization", required = false) String token,
            HttpServletRequest request) {
        try {
            Integer userId = getCurrentUserId(token);
            boolean success = deliveryService.saveBilling(deliveryId, billingData, userId);
            if (success) {
                logUtil.logAction(getCurrentUserIdLong(token), null, "c_delivery", deliveryId, "保存账单", request);
                return Result.success("操作成功", true);
            } else {
                return Result.error("操作失败");
            }
        } catch (Exception e) {
            log.error("保存账单失败", e);
            return Result.error("保存账单失败：" + e.getMessage());
        }
    }
    
    /**
     * 删除账单明细项
     */
    @RequiresPermission("edit")
    @PostMapping("/delete-billing-detail")
    public Result<Boolean> deleteBillingDetailItem(
            @RequestParam Long detailId,
            @RequestHeader(value = "Authorization", required = false) String token,
            HttpServletRequest request) {
        try {
            boolean success = deliveryService.deleteBillingDetailItem(detailId);
            if (success) {
                logUtil.logAction(getCurrentUserIdLong(token), null, "billing_details", detailId, "删除账单明细项", request);
                return Result.success("删除成功", true);
            } else {
                return Result.error("删除失败");
            }
        } catch (Exception e) {
            log.error("删除账单明细项失败", e);
            return Result.error("删除失败：" + e.getMessage());
        }
    }
}

